﻿#include <MaintenanceAndCorrection.h>

QVariantList logInfo;
extern QStringList runningList;

/**
 * @brief 构造函数
 */
MaintenanceAndCorrection::MaintenanceAndCorrection()
{
    udpClient=UdpClient::getInstance();
}

/**
 * @brief 析构函数
 */
MaintenanceAndCorrection::~MaintenanceAndCorrection()
{}

//恢复初始
Q_INVOKABLE void MaintenanceAndCorrection::restoreInitialState()
{

}

Q_INVOKABLE void MaintenanceAndCorrection::singleStop(QString serial){
    QString info=CommCommand::I().singleStop(serial);
    udpClient->ClientSendingData(common->GetSendData(info));
}

Q_INVOKABLE void MaintenanceAndCorrection::stop(){
    runningList.clear();
    QString info="62 00 00 3A 00 06 04 00 E7 2F 55 AA";
    udpClient->ClientSendingData(common->GetSendData(info));
}

Q_INVOKABLE void MaintenanceAndCorrection::saveData(){
    QString info="62 00 00 3C 00 05 0B E7 2F 55 AA";
    udpClient->ClientSendingData(common->GetSendData(info));
}

//复位
//type:类型 0:初始位置 1:实验位置
//serial: 编号 0:全部复位 ,其他传对应编号 1-6注射器 7转盘
//name:耗材名称 复位到初始位置可以不传
Q_INVOKABLE void MaintenanceAndCorrection::reset(QString type,QString serial,QString name)
{
    if(serial=="0" && runningList.length()>0){
        QMLSignal::I().emitSendResetMsg("1","0");
        return;
    }
    else if(serial=="9")
    {
        if(runningList.contains("1")||runningList.contains("2")||runningList.contains("3")||runningList.contains("4")||runningList.contains("5")||runningList.contains("6"))
        {
            QMLSignal::I().emitSendResetMsg("1","0");
            return;
        }
    }
    if(runningList.contains(serial)){
        QMLSignal::I().emitSendResetMsg("1",serial);
        return;
    }
    QString info;
    if(type=="0")//初始位置
    {
        info= CommCommand::I().resetInitialPosition(serial);
    }
    else //实验位置
    {
        QString code= common->getItemCode("3",name);
        info= CommCommand::I().resetExpPos(code,serial);
    }
    if(serial=="0"){
        for(int i=1;i<=7;i++){
            runningList.append(QString::number(i));
        }
    }
    else if(serial=="9"){
        for(int i=1;i<=6;i++){
            runningList.append(QString::number(i));
        }
    }
    else{
        runningList.append(serial);
    }

    udpClient->ClientSendingData(common->GetSendData(info));
}

//注射器
Q_INVOKABLE QVariantList MaintenanceAndCorrection::getSyringInfo(){
    QSqlDatabase db = dbHelper::openConnection();
    QSqlQuery query(db);
    QString sql="Select * From SyringToalInfo order by Serial";
    query.exec(sql);
    QVariantList result;
    while (query.next())
    {
        QStringList list;
        for (int i = 0; i < query.record().count(); ++i) {
            if(i==1){
                list.append(common->getItemName("3",query.value(i).toString()));
            }else{
                list.append(query.value(i).toString());
            }
        }
        result.append(list);
    }
    return result;
}

Q_INVOKABLE QVariantList MaintenanceAndCorrection::getSyringDetails(QString type){
    QString code=common->getItemCode("3",type);
    QSqlDatabase db = dbHelper::openConnection();
    QSqlQuery query(db);
    QString sql=QString("Select Name,Type,InsideDiameter,PublicErrand,InitialPosition,"
                        "Rate,RateUnit,ReductionRatio,ScrewLead,CircleStep,StepNumber,TotalSteps "
                        "From SyringeMaintenance Where "
                        "ConsumablesTypes='%1'").arg(code);
    query.exec(sql);
    QVariantList result;
    while (query.next())
    {
        QStringList info;

        for (int i = 0; i < query.record().count(); ++i) {
            info.append(query.value(i).toString());
        }
        result.append(info);
    }
    return result;
}

Q_INVOKABLE bool MaintenanceAndCorrection::delSyring(QString id){
    QSqlDatabase db = dbHelper::openConnection();
    QSqlQuery query(db);
    if(id=="0")
    {
        QString sql="Delete From SyringToalInfo";
        query.exec(sql);
        sql="Delete From SyringeMaintenance";
        return  query.exec(sql);
    }
    else
    {

        QString sql=QString("Delete From SyringeMaintenance Where ConsumablesTypes=("
                            "Select ConsumablesTypes "
                            "From SyringToalInfo Where Serial='%1')").arg(id);
        query.exec(sql);

        sql=QString("Delete From SyringToalInfo Where Serial='%1'").arg(id);
        query.exec(sql);

        sql=QString("Update SyringToalInfo Set Serial=Serial-1 Where Serial>'%1'").arg(id);
        query.exec(sql);
        return  true;
    }
}

//添加注射器
Q_INVOKABLE bool MaintenanceAndCorrection::saveSyring(QString type,QString serial,QString ConsumablesTypes,QVariantList mapList)
{
    QSqlDatabase db = dbHelper::openConnection();
    QSqlQuery query(db);
    QString code=common->getItemCode("3",ConsumablesTypes);

    QString sql=QString("Delete From SyringeMaintenance Where ConsumablesTypes='%1'").arg(code);
    query.exec(sql);

    int Num=1;
    foreach(QVariant syning,mapList){
        QStringList map=syning.value<QStringList>();
        sql=QString("Insert into SyringeMaintenance Values('%1','%2','%3','%4',"
                    "'%5','%6','%7','%8','%9','%10','%11','%12','%13','%14')").arg(code,QString::number(Num),map[0],
                map[1],map[2],map[3],map[4],map[5],map[6],map[7],map[8],map[9],map[10],map[11]);
        query.exec(sql);
        Num++;
    }
    Num--;
    if(type=="0")//新增
    {
        sql=QString("Insert or replace into SyringToalInfo Values('%1','%2','%3','%4')").arg(serial,code,QString::number(Num),common->GetDateTimeStr());
        query.exec(sql);
    }
    else//修改
    {
        sql=QString("Update SyringToalInfo set Num='%1',EditTime='%2' Where Serial='%3'").arg(QString::number(Num),common->GetDateTimeStr(),serial);
        query.exec(sql);
    }
    return  true;
}

Q_INVOKABLE QStringList MaintenanceAndCorrection::canInsertConsumablesType(){
    QStringList result;
    QSqlDatabase db = dbHelper::openConnection();
    QSqlQuery query(db);
    QString sql="Select value From Deftab Where id=3 and num not in(Select distinct ConsumablesTypes From SyringToalInfo)";
    query.exec(sql);
    while (query.next()) {
        result.append(query.value("value").toString());
    }
    return result;
}

Q_INVOKABLE int MaintenanceAndCorrection::getSyringNum(QString name){
    QSqlDatabase db = dbHelper::openConnection();
    QSqlQuery query(db);
    QString sql=QString("Select value_2 From Deftab Where value='%3' and id='3'").arg(name);
    query.exec(sql);
    int result;
    while (query.next())
    {
        result=query.value("value_2").toInt();
    }
    return result;
}

//注射器执行
Q_INVOKABLE void MaintenanceAndCorrection::runningSyring(QString type,QString num, QString speed,QString pos){
    if(runningList.contains(num))
    {
        QMLSignal::I().emitSendSyringRunMsg("1",num);
        return;
    }
    runningList.append(num);
    QString numStr=common->TenToSixteen(num.toInt(),2);
    QString speedStr=common->TenToSixteen(qRound(speed.toDouble()),4);
    QString posStr=common->TenToSixteen(qRound(pos.toDouble()),8);
    QString typeCode=common->getItemCode("3",type);
    QString typeStr=common->TenToSixteen(typeCode.toInt(),4);
    QString info=QString("62 00 00 3C 00 0E 06 %1 %2 %3 %4 E7 2F 55 AA").arg(numStr,speedStr,posStr,typeStr);
    udpClient->ClientSendingData(common->GetSendData(info));
}

//计算步数
Q_INVOKABLE QStringList MaintenanceAndCorrection::calculateSteps(QString speed,QString diameter, QString reductionRatio,QString screwLead,QString circleStep,QString distance){
    QStringList result;
    QStringList reList=reductionRatio.split(':');
    double newSpeed=speed.toDouble();

    // 速度单位:ml/min 转成mm/s 距离从ml 转成 mm
    if(!diameter.isNull() && !diameter.isEmpty())
    {
        newSpeed=common->minToSecond(speed,diameter).toDouble();

        double r=diameter.toDouble()/2;
        double round=3.1415*r*r;
        distance=QString::number(distance.toDouble()*1000/round);
    }

    double stepNum=distance.toDouble()/screwLead.toDouble()*circleStep.toDouble()*reList[1].toDouble();
    double time=distance.toDouble()/newSpeed;
    double stepNumber= stepNum/time;

    result.append(QString::number(qRound(stepNumber)));
    result.append(QString::number(qRound(stepNum)));

    return result;
}

Q_INVOKABLE QString MaintenanceAndCorrection::getSerial()
{
    QSqlDatabase db = dbHelper::openConnection();
    QSqlQuery query(db);
    QString serial;
    QString sql="Select max(Serial)+1 as Serial From SyringToalInfo";
    query.exec(sql);
    while (query.next()) {
        serial=query.value("Serial").toString().isNull()?"1":query.value("Serial").toString();
    }
    return serial;
}

Q_INVOKABLE QString MaintenanceAndCorrection::checkSyringParameter(QString type,QString nj,QString distance,QString speed,QString unit,QString jsb,QString dc,QString qb)
{
    QStringList list=type.split("ml");
    //    double volume= list[0].toDouble()*1000;
    if(unit=="mL/Min"){
        //        if(distance.toDouble()>list[0].toDouble())
        //        {

        //            double maxDistance=volume/area;
        //            if(distance.toDouble()>qFloor(maxDistance))
        //            {
        //                return QString("起始位置不能超出%1mL,请重新填写").arg(list[0]);
        //            }
        //        }

        //        double result = min * 1000 / (60*round);
        QString realJsb=jsb.split(":")[1];
        double maxSpeed=qFloor((48000*dc.toDouble())/(qb.toDouble()*realJsb.toDouble()));

        double maxMinSpeed=common->secondToMin(maxSpeed,nj.toDouble());
        if(speed.toDouble()>maxMinSpeed){
            return  QString("速度不能超出%1mL/Min,请重新填写").arg(QString::number(maxMinSpeed));
        }
    }
    else{
        //        double area=3.1415*nj.toDouble()*nj.toDouble()/4;
        //        double maxDistance=volume/area;
        //        if(distance.toDouble()>qFloor(maxDistance))
        //        {
        //            return QString("起始位置不能超出%1mm,请重新填写").arg(QString::number(qFloor(maxDistance)));
        //        }

        QString realJsb=jsb.split(":")[1];
        double maxSpeed=qFloor((48000*dc.toDouble())/(qb.toDouble()*realJsb.toDouble()));

        if(speed.toDouble()>maxSpeed){
            return  QString("速度不能超出%1mm/s,请重新填写").arg(QString::number(maxSpeed));
        }
    }
    return "";
}

//导出
Q_INVOKABLE int MaintenanceAndCorrection::exportSyringConfig(QString id)
{

    QString path="";
    QString  savePath = QFileDialog::getSaveFileName(NULL, "保存", path,"Wlk files(*.txt)");
    if(savePath.isEmpty()&&savePath.isNull()){
        return -1;
    }

    QFile file(savePath);
    file.open(QIODevice::Append);

    QTextStream out(&file);  // QTextStream会自动将 Unicode 编码同操作系统的编码进行转换
    QTextCodec* codec = QTextCodec::codecForName("GBK");
    out.setCodec(codec);

    QString code= common->getItemCode("3",id);
    out<<id+"\n";//标记耗材名称

    QSqlDatabase db = dbHelper::openConnection();
    QSqlQuery query(db);
    QString sql=QString("Select * From SyringeMaintenance Where ConsumablesTypes='%1' ").arg(code);
    query.exec(sql);

    while (query.next())
    {
        QString addSql=QString("Insert into SyringeMaintenance Values('%1','%2','%3','%4','%5','%6','%7','%8',"
                               "'%9','%10','%11','%12','%13','%14')").arg(
                    query.value("ConsumablesTypes").toString(),query.value("Id").toString(),
                    query.value("Name").toString(),query.value("Type").toString(),
                    query.value("InsideDiameter").toString(),query.value("PublicErrand").toString(),
                    query.value("InitialPosition").toString(), query.value("Rate").toString(),
                    query.value("RateUnit").toString(),query.value("ReductionRatio").toString(),
                    query.value("ScrewLead").toString(),query.value("CircleStep").toString(),
                    query.value("StepNumber").toString(),query.value("TotalSteps").toString());
        out<<addSql+"\n";
    }

    file.close();
    return true;
}

//导入
Q_INVOKABLE int MaintenanceAndCorrection::importSyringConfig()
{
    QStringList sfilePath;
    QFileDialog *fDialog=new QFileDialog(NULL,"file dlg","","Txt files(*.txt)");
    if(fDialog->exec()==QFileDialog::Accepted)
    {
        sfilePath = fDialog->selectedFiles();
    }
    if(sfilePath.length()<=0)
    {
        return  1;
    }
    QString filepath = sfilePath[0];
    QFile file(filepath);
    if(!file.exists()){
        return -1;
    }
    file.open(QIODevice::ReadOnly | QIODevice::Text);
    QTextStream txtInput(&file);

    QSqlDatabase db = dbHelper::openConnection();
    QSqlQuery query(db);
    int i=0;
    QString code;
    bool exist=false;
    db.transaction();
    while (!txtInput.atEnd())
    {
        QString lineStr = txtInput.readLine();

        if(i==0)
        {
            QString sql=QString("Select count(*) Num From Deftab Where value='%1' and id='3'").arg(lineStr);
            query.exec(sql);
            while (query.next()) {
                exist=query.value("Num").toInt()>0;
            }
            if(exist)
            {
                code=common->getItemCode("3",lineStr);
                QString  sql=QString("Delete From SyringeMaintenance Where ConsumablesTypes='%1'").arg(code);
                query.exec(sql);
            }
            else
            {
                QString sql="Select max(Num)+1 as Serial From Deftab Where id='3'";
                query.exec(sql);
                while (query.next()) {
                    code=query.value("Serial").toString().isNull()?"1":query.value("Serial").toString();
                }

                sql=QString("Insert into Deftab values('3','0','%1','%2','6')").arg(code,lineStr);
                query.exec(sql);
            }
            i++;
        }
        else
        {
            if(!lineStr.contains("Insert into SyringeMaintenance Values")){
                db.rollback();
                return -2;
            }

            QStringList strList = lineStr.split("'");
            strList[1]=code;
            lineStr = strList.join("'");
            query.exec(lineStr);
        }
    }
    db.commit();
    if(exist)
    {
        bool existSyring=false;
        QString sql=QString("Select count(*) Num From SyringToalInfo Where ConsumablesTypes='%1'").arg(code);
        query.exec(sql);
        while (query.next())
        {
            existSyring=query.value("Num").toInt()>0;
        }

        if(existSyring){
            sql=QString("Update SyringToalInfo Set Num=(Select count(*) From SyringeMaintenance Where ConsumablesTypes='%1'),EditTime='%2' Where ConsumablesTypes='%1'").arg(code,common->GetDateTimeStr());
            query.exec(sql);
        }
        else{
            QString sql=QString("Insert into SyringToalInfo Values((Select Case When max(Serial)+1 isNull then 1 else max(Serial)+1 end From SyringToalInfo),'%1',(Select count(*) From SyringeMaintenance Where ConsumablesTypes='%1'),'%2')").arg(code,common->GetDateTimeStr());
            query.exec(sql);
        }
    }
    else{
        QString sql=QString("Insert into SyringToalInfo Values((Select Case When max(Serial)+1 isNull then 1 else max(Serial)+1 end From SyringToalInfo),'%1',(Select count(*) From SyringeMaintenance Where ConsumablesTypes='%1'),'%2')").arg(code,common->GetDateTimeStr());
        query.exec(sql);
    }
    QString sql=QString("Update Deftab Set value_2=(Select Count(*) From SyringeMaintenance Where ConsumablesTypes='%1') Where id='3' and num='%1'").arg(code);
    query.exec(sql);

    return 0;
}


//转盘

//读取
Q_INVOKABLE void MaintenanceAndCorrection::readPos(QString pos){
    QString code = common->TenToSixteen(pos.toInt(),2);
    QString info=QString("62 00 00 3C 00 06 08 07 %1 E7 2F 55 AA").arg(code);
    udpClient->ClientSendingData(common->GetSendData(info));
}

//执行
Q_INVOKABLE void MaintenanceAndCorrection::turnTurnTable(QString pos,QString step){
    QString posStr=common->TenToSixteen(pos.toInt(),2);
    QString stepInfo= common->TenToSixteen(step.toInt(),8);
    QString info=QString("62 00 00 3C 00 0B 09 07 %1 %2 E7 2F 55 AA").arg(posStr,stepInfo);
    udpClient->ClientSendingData(common->GetSendData(info));
}

Q_INVOKABLE void MaintenanceAndCorrection::setInitialPosition(QString pos,QString type)
{
    QString code= common->getItemCode("3",type);
    QString posStr=common->TenToSixteen(pos.toInt(),2);
    QString typeStr=common->TenToSixteen(code.toInt(),4);
    QString info=QString("62 00 00 3C 00 09 0A 07 %1 %2 E7 2F 55 AA").arg(posStr,typeStr);
    udpClient->ClientSendingData(common->GetSendData(info));

    QSqlDatabase db = dbHelper::openConnection();
    QSqlQuery query(db);
    QString sql=QString("Insert or Replace into TurnTableInformation Values('%1','%2')").arg(code,pos);
    query.exec(sql);
}

Q_INVOKABLE void MaintenanceAndCorrection::setAirPumpPressure(QString open,QString close)
{
    QString info=CommCommand::I().AirPumpPressure("1",open,close);
    udpClient->ClientSendingData(common->GetSendData(info));
}

Q_INVOKABLE void MaintenanceAndCorrection::readAirPumpPressure(){
    QString info= CommCommand::I().AirPumpPressure("2","0","0");
    udpClient->ClientSendingData(common->GetSendData(info));
}

//日志
Q_INVOKABLE QVariantList MaintenanceAndCorrection::getLog(){
    return  logInfo;
}

Q_INVOKABLE void MaintenanceAndCorrection::delLog(){
    logInfo.clear();
}

Q_INVOKABLE void MaintenanceAndCorrection::exportLog(){
    QString path="/path/to/default/";
    QString  savePath = QFileDialog::getSaveFileName(NULL, "保存", path,"Wlk files(*.txt)");
    if(savePath.isEmpty()&&savePath.isNull()){
        return;
    }

    QFile file(savePath);
    file.open(QIODevice::Append);

    foreach(QVariant log,logInfo){
        QStringList map=log.value<QStringList>();
        file.write((map[1]+ ": \n" +map[2] +"["+map[0] + "]  " + "\n").toUtf8());
    }
    file.close();
}

Q_INVOKABLE QJsonArray MaintenanceAndCorrection::getFaultInformation(QString module)
{
    QSqlDatabase db = dbHelper::openConnection();
    QSqlQuery query(db);
    QString sql=QString("Select Serial,ErrorCode,ErrorName,ErrorMethod,IsBlocked From FaultInformation Where Module='%1'").arg(module);
    query.exec(sql);

    QStringList serial;
    QStringList errorCode;
    QStringList errorName;
    QStringList errorMethod;
    QStringList isBlocked;

    while (query.next()) {
        serial.append(query.value("Serial").toString());
        errorCode.append(query.value("ErrorCode").toString());
        errorName.append(query.value("ErrorName").toString());
        errorMethod.append(query.value("ErrorMethod").toString());
        isBlocked.append(query.value("IsBlocked").toString());
    }
    QJsonArray result;
    QJsonObject rec;
    for(int i = 0; i < serial.size(); ++i) {
        rec.insert("serial", serial[i]);
        rec.insert("errorCode", errorCode[i]);
        rec.insert("errorName", errorName[i]);
        rec.insert("errorMethod", errorMethod[i]);
        rec.insert("isBlocked", isBlocked[i]);

        result.append(rec);
    }
    return result;
}

Q_INVOKABLE void MaintenanceAndCorrection::updateFaultInformation(QString module,QString serial,QString errorName,QString errorMethod,QString isBlocked)
{
    QSqlDatabase db = dbHelper::openConnection();
    QSqlQuery query(db);
    QString sql=QString("Update FaultInformation set ErrorName='%1',ErrorMethod='%2',IsBlocked='%3' Where Module='%4' and Serial='%5'").arg(errorName,errorMethod,isBlocked,module,serial);
    query.exec(sql);
}

Q_INVOKABLE bool MaintenanceAndCorrection::addFaultInformation(QString module){
    QSqlDatabase db = dbHelper::openConnection();
    QSqlQuery query(db);
    QString serial;
    QString sql=QString("Select max(serial) serial From FaultInformation Where module='%1'").arg(module);
    query.exec(sql);
    while (query.next()) {
        serial=query.value("serial").toString();
    }

    QString maxErrorCode;
    sql=QString("Select ErrorCode From FaultInformation Where module='%1' and serial='%2'").arg(module,serial);
    query.exec(sql);
    while (query.next())
    {
        maxErrorCode=query.value("ErrorCode").toString();
    }
    int tenCode= common->SixteenToTen(maxErrorCode).toInt();
    QString newCode=common->TenToSixteen(tenCode+1,2).toUpper();
    sql=QString("Insert into FaultInformation values('%1','%2','%3','','是','否')").arg(module,QString::number(serial.toInt()+1),newCode);
    return query.exec(sql);
}

